package com.he.springcloud.service.impl;

import cn.hutool.core.util.IdUtil;
import com.he.springcloud.service.HystrixPaymentService;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @Classname: HystrixPaymentServiceImpl
 * @Description: 熔断服务接口实现类
 * @Date: 2021/9/8
 * @Author: huwei
 */
@Service
@Slf4j
public class HystrixPaymentServiceImpl implements HystrixPaymentService {

    // region 服务降级方法

    @Override
    public String getDataIndoSuccess(Integer id) {
        return "getDataIndoSuccess_链接成功{链接池:" + Thread.currentThread().getName() + ",id:" + id + "}";
    }

    /**
     * @HystrixCommand(fallbackMethod = "getDataInfoErrorMethod",commandProperties = {
     *          @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "3000")
     * })
     * 此注解表示当这个方法出现timeoutInMilliseconds线程的问题后,超过3秒钟,会调用getDataInfoErrorMethod方法进行兜底
     */
    @HystrixCommand(fallbackMethod = "getDataInfoErrorMethod", commandProperties = {
            @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "15000")
    })
    @Override
    public String getDataInfoError(Integer id) {
        int threadSleep = 1;
        try {
            TimeUnit.SECONDS.sleep(threadSleep);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "getDataInfoError_链接成功{链接池:" + Thread.currentThread().getName() + ",id:" + id + ",处理了" + threadSleep + "秒}";
    }

    /**
     * 服务降级时调用的方法
     */
    public String getDataInfoErrorMethod(Integer id) {
        log.info("服务降级了!");
        return "8001调用的方法失败了!id:" + id + "___服务降级";
    }
    // endregion

    // region 服务熔断

    /**
     * 服务熔断实现类
     *
     * 注解表示在10000毫秒(1秒)内请求10次,如果失败率达到60%就启动断路器,调用getDataErrorForErrorFuseMethod方法返回
     *
     * @param id
     * @return
     */
    @Override
    @HystrixCommand(fallbackMethod = "getDataErrorForErrorFuseMethod", commandProperties = {
            @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), // 是否开启断路器
            @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), // 请求次数
            @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"), //时间窗口期
            @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") // 失败率达到多少后跳闸
    })
    public String getDataErrorForErrorFuse(Integer id){
        if(id < 0){
            throw new RuntimeException("ID不能小于3") ;
        }
        String simpleUuid = IdUtil.simpleUUID();
        return Thread.currentThread().getName()+",调用成功,流水号是:"+simpleUuid;
    }

    /**
     * 服务熔断时调用的方法
     */
    public String getDataErrorForErrorFuseMethod(Integer id){
        log.info("服务熔断了");
        return "服务熔断方法被调用了,id:"+id;
    }
    // endregion
}
